
#pragma once

#include <map>

namespace ATools
{
	//
	template<class ObjectType, class CreatorBase>
	class TObjectCreator : public CreatorBase
	{
	public:
		virtual ObjectType* Create(void)
		{
			return new ObjectType();
		}
	};

	//////////////////////////////////////////////////////////////////////////
	template<class ObjectType,typename DentifierType, class CreatorBase>
	class TObjectFactory
	{
		typedef std::map<DentifierType, CreatorBase*> ObjectCreatorMap;
	public:
		// register an operator with an id
		bool RegisterObject(const DentifierType& id, CreatorBase* pCreator)
		{
			return m_mapCreators.insert(ObjectCreatorMap::value_type(id, pCreator)).second;
		}

		// remove an operator registered
		bool UnRegisterObject(const DentifierType& id)
		{
			ObjectCreatorMap::iterator it = m_mapCreators.find(id);
			if(it != m_mapCreators.end())
			{
				delete it->second;
				it->second = NULL;
				m_mapCreators.erase(it);
				return true;
			}

			return false;
		}

		// create an operator by id
		ObjectType* CreateObject(const DentifierType& id) const
		{
			ObjectCreatorMap::const_iterator it = m_mapCreators.find(id);
			if( it != m_mapCreators.end())
			{
				return (it->second)->Create();
			}

			return NULL;
		}

	private:

		ObjectCreatorMap m_mapCreators;
	};

}